package org.wdcode.back.action.login;

import java.util.List;
import java.util.Map;

import org.wdcode.back.constants.I18NKey;
import org.wdcode.back.helper.LoginLogsHelper;
import org.wdcode.back.helper.MenuHelper;
import org.wdcode.back.helper.OperateHelper;
import org.wdcode.back.helper.UserHelper;
import org.wdcode.back.po.LoginLogs;
import org.wdcode.back.po.User;
import org.wdcode.back.service.LoginLogsService;
import org.wdcode.back.service.LoginService;
import org.wdcode.base.struts.action.BaseAction;

import org.wdcode.common.tools.Conversion;
import org.wdcode.common.util.CommonUtil;
import org.wdcode.common.util.DateUtil;
import org.wdcode.core.concurrent.ExecutorFactory;
import org.wdcode.web.tools.VerifyCode;
import org.wdcode.web.util.RequestUtil;
import org.wdcode.web.util.SessionUtil;

/**
 * 登录Action
 * @author WD
 * @since JDK6
 * @version 1.0 2009-07-14
 */
public final class LoginAction extends BaseAction {
	// 序列化 ID
	private static final long	serialVersionUID	= 5542364549112574333L;
	// 登录状态 成功
	private final static short	YES					= 1;
	// 登录状态 失败
	private final static short	NO					= 0;

	// 登录业务
	private LoginService		service;
	// 登录日志业务
	private LoginLogsService	loginLogsService;

	// 用户实体
	private User				user;
	// 验证码
	private String				verifyCode;

	/**
	 * 跳转方法
	 */
	public String index() throws Exception {
		// 判断有用户登录信息
		if (getUserId() > 0) {
			// 跳转到成功页
			return SUCCESS;
		} else {
			// 跳转到登录页
			return LOGIN;
		}
	}

	/**
	 * 主页
	 */
	public String main() throws Exception {
		// 获得用户ID
		int uid = getUserId();
		// 判断有用户登录信息
		if (uid > 0) {
			// 获得权限ID
			int roleId = Conversion.toInt(UserHelper.getHelper().get(uid).getRoleId());
			// 判断有权限登陆
			if (roleId > 0) {
				// 声明权限列表
				List<Integer> lsOperate = null;
				// 检查用户权限缓存
				if (CommonUtil.isEmpty(getOperateHelper().getUserOperate(uid))) {
					// 获得权限列表
					lsOperate = service.getOperate(roleId);
					// 把权限操作保存到缓存中
					getOperateHelper().setUserOperate(uid, lsOperate);
				}
				// 检查用户菜单
				if (CommonUtil.isEmpty(getMenuHelper().getUserMenu(uid))) {
					// 获得菜单保存到缓存中
					getMenuHelper().setUserMenu(uid, service.getMenu(lsOperate));
				}
			} else {
				return LOGIN;
			}
		}
		// 跳转到成功页
		return SUCCESS;
	}

	/**
	 * 获得验证码方法
	 * @return
	 * @throws Exception
	 */
	public String verifyCode() throws Exception {
		// 获得验证码
		VerifyCode.make(getRequest(), getResponse());
		// 返回到登录页
		return null;
	}

	/**
	 * 执行退出
	 */
	public String loginOut() throws Exception {
		// 销毁用户session
		SessionUtil.close(getSession());
		// 设置用户ID为0
		setUserId(0);
		// 返回登录页
		return SUCCESS;
	}

	/**
	 * 执行登录方法
	 */
	public String execute() throws Exception {
		// 验证验证码
		if (!VerifyCode.getValue(getRequest()).equals(verifyCode)) {
			// 添加错误信息
			addFieldError(I18NKey.VERIFY_CODE_ERROR);
			// 返回登陆页
			return INPUT;
		}
		// 清除验证码
		VerifyCode.removeValue(getRequest(), getResponse());
		// 加密密码
		user.setPassword(getUserHelper().getPassword(user.getPassword()));
		// 获得IP
		final String ip = RequestUtil.getIP(getRequest());
		// 登录验证
		if (service.login(user)) {// 登录成功
			// 获得权限ID
			int roleId = Conversion.toInt(user.getRoleId());
			// 判断是否有权限登录
			if (roleId > 0) {
				// 用户ID
				int userId = user.getId();
				// 获得权限列表
				List<Integer> lsOperate = service.getOperate(roleId);
				// 把用户实体保存到属性中
				setUserId(userId);
				// 把权限操作保存到缓存中
				getOperateHelper().setUserOperate(userId, lsOperate);
				// 获得菜单保存到缓存中
				getMenuHelper().setUserMenu(userId, service.getMenu(lsOperate));
				// 添加登录日志
				ExecutorFactory.getFactory().getInstance().execute(new Runnable() {
					@Override
					public void run() {
						addLoginLogs(YES, ip);
					}
				});
				// 跳转到成功页
				return SUCCESS;
			} else {
				// 添加错误信息
				addFieldError(I18NKey.LOGIN_ROLE_NOT);
				// 返回到登录页
				return INPUT;
			}
		} else {// 登录失败
			// 添加错误信息
			addFieldError(I18NKey.LOGIN_FAIL);
			// 添加登录日志
			ExecutorFactory.getFactory().getInstance().execute(new Runnable() {
				@Override
				public void run() {
					addLoginLogs(NO, ip);
				}
			});
			// 返回到登录页
			return INPUT;
		}
	}

	/**
	 * 获得用户实体
	 * @return 用户实体
	 */
	public User getUser() {
		return user;
	}

	/**
	 * 设置用户实体
	 * @param user 用户实体
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * 获得登录业务
	 * @return 登录业务
	 */
	public LoginService getService() {
		return service;
	}

	/**
	 * 设置登录业务
	 * @param loginService 登录业务
	 */
	public void setService(LoginService loginService) {
		this.service = loginService;
	}

	/**
	 * 获得登录日志业务
	 * @return 登录日志业务
	 */
	public LoginLogsService getLoginLogsService() {
		return loginLogsService;
	}

	/**
	 * 设置登录日志业务
	 * @param loginLogsService 登录日志业务
	 */
	public void setLoginLogsService(LoginLogsService loginLogsService) {
		this.loginLogsService = loginLogsService;
	}

	/**
	 * 获得验证码
	 * @return 验证码
	 */
	public String getVerifyCode() {
		return verifyCode;
	}

	/**
	 * 设置验证码
	 * @param verifyCode 验证码
	 */
	public void setVerifyCode(String verifyCode) {
		this.verifyCode = verifyCode;
	}

	/**
	 * 获得验证码长度
	 * @return 验证码长度
	 */
	public int getVerifyLength() {
		return VerifyCode.getLength();
	}

	/**
	 * 获得用户助手
	 * @return 用户助手
	 */
	public final UserHelper getUserHelper() {
		return UserHelper.getHelper();
	}

	/**
	 * 获得菜单助手
	 * @return 菜单助手
	 */
	public final MenuHelper getMenuHelper() {
		return MenuHelper.getHelper();
	}

	/**
	 * 获得操作助手
	 * @return 操作助手
	 */
	public final OperateHelper getOperateHelper() {
		return OperateHelper.getHelper();
	}

	/**
	 * 获得用户菜单
	 * @return 用户菜单
	 */
	public final Map<Integer, List<Integer>> getUserMenu() {
		return getMenuHelper().getUserMenu(getUserId());
	}

	/**
	 * 添加登录日志
	 * @param state 登录状态 0 登录失败 1登录成功
	 */
	private void addLoginLogs(short state, String ip) {
		// 登录日志实体
		LoginLogs logs = LoginLogsHelper.getHelper().newInstance();
		// 添加属性
		logs.setName(user.getName());
		logs.setUserId(user.getId());
		logs.setState(state);
		logs.setIp(ip);
		logs.setCreateDate(DateUtil.getTime());
		// 添加日志
		loginLogsService.insert(logs);
	}
}
